package com.hyperfix.simulator.senor;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @author JiangChunYu
 * 2024/3/19
 */
@Data
@AllArgsConstructor
public class CombinationSenor implements InstantParamSenor {
    private int station;
    private int pipeline;

    private static final InstantParamSenor TEMPERATURE_SENOR = new TemperatureSenor();
    private static final InstantParamSenor PRESSURE_SENOR = new PressureSenor();
    private static final InstantParamSenor OIL_PRESSURE_SENOR = new OilPressureSenor();
    private static final InstantParamSenor CASING_PRESSURE_SENOR = new CasingPressureSenor();
    private static final InstantParamSenor DIFF_PRESSURE_SENOR = new DiffPressureSenor();
    private static final InstantParamSenor FLOW_SENOR = new FlowSenor();
    private static final TotalFlowSenor TOTAL_FLOW_SENOR = new TotalFlowSenor();

    /**
     * 对数据进行编码
     * 站场 7bit 管线 9bit 共2byte
     * 温度 8bit整数 1bit符号 7bit小数 共2byte
     * 压力 8bit整数 1bit符号 7bit小数 共2byte
     * 油压 8bit整数 1bit符号 7bit小数 共2byte
     * 套压 8bit整数 1bit符号 7bit小数 共2byte
     * 差压 15bit整数 1bit符号 共2byte
     * 瞬时流量 16bit整数 共2byte
     * 总流量 24bit整数 共3byte
     * 总计 17byte
     *
     * @return 编码后的数据
     */
    @Override
    public byte[] nextData() {
        byte[] temperature = TEMPERATURE_SENOR.nextData();
        byte[] pressure = PRESSURE_SENOR.nextData();
        byte[] oilPressure = OIL_PRESSURE_SENOR.nextData();
        byte[] casingPressure = CASING_PRESSURE_SENOR.nextData();
        byte[] diffPressure = DIFF_PRESSURE_SENOR.nextData();
        byte[] flow = FLOW_SENOR.nextData();
        byte[] totalFlow = TOTAL_FLOW_SENOR.nextData(this.pipeline);

        return assembleData(temperature, pressure, oilPressure, casingPressure, diffPressure, flow, totalFlow);
    }

    /**
     * 组装数据
     *
     * @param temperature    温度
     * @param pressure       压力
     * @param oilPressure    油压
     * @param casingPressure 套压
     * @param diffPressure   差压
     * @param flow           流量
     * @param totalFlow      总流量
     * @return {@link byte[]}
     */
    private byte[] assembleData(byte[] temperature, byte[] pressure, byte[] oilPressure, byte[] casingPressure, byte[] diffPressure, byte[] flow, byte[] totalFlow) {
        byte[] data = new byte[17];
        data[0] = (byte) ((byte) (this.station << 1) | ((this.pipeline >>> 8) & 0x00000001));
        data[1] = (byte) this.pipeline;
        data[2] = temperature[0];
        data[3] = temperature[1];
        data[4] = pressure[0];
        data[5] = pressure[1];
        data[6] = oilPressure[0];
        data[7] = oilPressure[1];
        data[8] = casingPressure[0];
        data[9] = casingPressure[1];
        data[10] = diffPressure[0];
        data[11] = diffPressure[1];
        data[12] = flow[0];
        data[13] = flow[1];
        data[14] = totalFlow[0];
        data[15] = totalFlow[1];
        data[16] = totalFlow[2];
        return data;
    }
}
